'''
@author: Jang, KyoungRok [20114470]
'''
from libsvm.svmutil import *
import csv
#-t kernel_type : set type of kernel function (default 2)
#    0 -- linear: u'*v
#    1 -- polynomial: (gamma*u'*v + coef0)^degree
#    2 -- radial basis function: exp(-gamma*|u-v|^2)
#    3 -- sigmoid: tanh(gamma*u'*v + coef0)
#    4 -- precomputed kernel (kernel values in training_set_file)
#-d degree : set degree in kernel function (default 3)
#-g gamma : set gamma in kernel function (default 1/num_features)
#-r coef0 : set coef0 in kernel function (default 0)
#-c cost : set the parameter C of C-SVC, epsilon-SVR, and nu-SVR (default 1)
#-wi weight : set the parameter C of class i to weight*C, for C-SVC (default 1)
#-v n: n-fold cross validation mode
def test_linear(prob, test_set):
    KERNEL = 0
    C = [1, 10, 100, 1000, 10000, 100000, 500000]
    
    print '[Default]'
    # build parameter
    param = svm_parameter('-t %d -q' % KERNEL)

    # build model 
    model = svm_train(prob, param)
    
    # predict
    svm_predict(test_set[0], test_set[1], model)
    
    f = open('linear.out', 'wb')
    writer = csv.writer(f)
    acc = {}
    for c in C:
        print '[C = %d]' % c
        
        # build parameter
        param = svm_parameter('-t %d -c %d -q' % (KERNEL, c))
    
        # build model 
        model = svm_train(prob, param)
        
        # predict
        result = svm_predict(test_set[0], test_set[1], model)
        
        acc[c] = result[1][0]
        
    headers = []
    values = []
    for header in sorted(acc.keys()):
        headers.append(header)
        values.append(acc[header])
        
    writer.writerow(headers)
    writer.writerow(values)
    f.close()
        
def test_polynomial(prob, test_set):
    KERNEL = 1
    C = [10, 100, 1000, 10000, 100000]
    G = [1, 0.1, 0.01, 0.001, 0.0001, 0.00001]
    R = range(0, 11)
    D = range(0, 11)
    
    for d in D:
        print '[C = 10000, G = default, R = 2, D = %d]' % d
        
        # build parameter
        param = svm_parameter('-t %d -c %d -r %d -d %d -q' % (KERNEL, 10000, 3, d))
    
        # build model 
        model = svm_train(prob, param)
        
        # predict
        svm_predict(test_set[0], test_set[1], model)

def test_rbf(prob, test_set):
    KERNEL = 2
    C = [1, 10, 100, 1000, 10000, 100000]
    G = [10, 1, 0.1, 0.01, 0.001, 0.0001, 0.00001]
    
    f = open('rbf.out', 'wb')
    writer = csv.writer(f)
    writer.writerow(C)
    
    for g in G:
        print 'gamma = %f' % g
        row = []
        
        for c in C:
            # build parameter
            param = svm_parameter('-t %d -c %d -g %f -q' % (KERNEL, c, g))
        
            # build model 
            model = svm_train(prob, param)
            
            # predict
            result = svm_predict(test_set[0], test_set[1], model)
            
            acc = result[1][0]
            row.append(acc)
            
        writer.writerow(row)
    
    f.close()
    
def run_best_kenel(prob, unknown_set):
    KERNEL = 1
    
    print '[kernel = polynomial, C = 10000, R = 2, D = 2]'
    
    # build parameter
    param = svm_parameter('-t %d -c %d -r %d -d %d -q' % (KERNEL, 10000, 2, 2))

    # build model 
    model = svm_train(prob, param)
    
    # predict
    result = svm_predict(unknown_set[0], unknown_set[1], model)
    
    # return predicted labels
    return result[0]

def test_sigmoid(prob, test_set):
    KERNEL = 3
    C = [1, 10, 100, 1000, 10000, 100000]
    G = [10, 1, 0.1, 0.01, 0.001, 0.0001, 0.00001]
    R = range(0, 11)
    
    print '[Default]'
    # build parameter
    param = svm_parameter('-t %d -q' % KERNEL)

    # build model 
    model = svm_train(prob, param)
    
    # predict
    svm_predict(test_set[0], test_set[1], model)
    
    for r in R:
        print '[C = 100, G = default, R = %d]' % r
        
        # build parameter
        param = svm_parameter('-t %d -c %d -r %d -q' % (KERNEL, 100, r))
    
        # build model 
        model = svm_train(prob, param)
        
        # predict
        svm_predict(test_set[0], test_set[1], model)
    
if __name__ == '__main__':
#    KERNEL = 2      # TYPE OF KERNEL      
#    C = 1        # COST
#    G = 0.5       # GAMMA               
#    R = 0           # coef0               
#    WI = 0          # WEIGHT              
#    V = 2           # CV
    
    # open file
    out = open('20114470_SVM.out', 'w')
    
    # load the raw sets
    training_set = svm_read_problem('./data/SVM_training_set.txt')
    test_set = svm_read_problem('./data/SVM_test_set.txt')
    unknown_set = svm_read_problem('./data/SVM_unknown_set.txt')
    
    # build problem
    prob = svm_problem(training_set[0], training_set[1])
    
    # test kernel
#    test_polynomial(prob, test_set)

    # run best kernel on the unknown data
    labels = run_best_kenel(prob, unknown_set)
    
    for label in labels:
        out.write(str(label))
        out.write('\n')
    
    # close the file
    out.close()
    
    